﻿// ActionScript file
/**
 * @usage 滚动条初始化类
 * 
 * @experience
 * 当scrollContentHeight不是绝对赋值时，即通过[content].height-[mask].height动态取得时，需注意以下几点：
 * 1、包含静态文本的MovieClip的实际宽高与显示宽高会发生偏差，
 * 	如实际高度为499，[mc].height则为561.35,此会造成滚动距离偏差.
 * 2、遮罩被缩放后(scaleX/scaleY)发生改变时，会取不到显示宽高.
 * 
 * <code>
 * var obj:Object = { 
							content:this.showLot,
							mask:this.maskShape,
							thumb:this.scrollBar['slider'],
							track:this.scrollBar['bar'],
							up_btn:this.scrollBar['btnUp'],
							down_btn:this.scrollBar['btnDown'] };
	scrollBoxUIConfig = obj;
	initialize();
	//保存滚动栏与遮罩高度
	var mHeight:Number = this.maskShape.height;
	this.scrollBar.bg.height = mHeight;
	this.scrollBar.bar.height = mHeight - (this.scrollBar['btnUp'].height + this.scrollBar['btnDown'].height);
	this.scrollBar['btnDown'].y = (this.scrollBar.bar.height + this.scrollBar.bar.y);
	
 * </code>
 * 
 */
package org.nickro.project.widgets{
	import flash.display.DisplayObject;
	import flash.display.InteractiveObject;
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import org.nickro.project.events.ScrollEvent;
	import org.nickro.externallibrary.tween.TweenLite;
	import org.nickro.externallibrary.tween.easing.*;
	import org.nickro.project.web.BrowserUtil;
	
	public class ScrollBox extends MovieClip
	{
		public static const MOVE:String = "move";
		//thumb的最小/最大的Y轴坐标
		public var yMax:Number;
		public var yMin:Number;
		//滚动内容与滚动遮罩之间的Y轴落差
		private var yOffset:Number;
		//移动百分比
		private var _percent:Number = 0;
		//移动速度
		private var _speed:Number = .1;
		
		public function ScrollBox()
		{
			/**
			 * 链接到库元件
			 */
			/*if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);*/
		}
		public function initialize():void
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		private function init(e:Event = null):void
		{
			addEventListener(Event.ENTER_FRAME, delayCall); 
			addEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
		}
		//滚动轨迹
		private var track:InteractiveObject;
		//滚动按钮
		private var thumb:InteractiveObject;
		//向上按钮
		private var up_btn:InteractiveObject;
		//向下按钮
		private var down_btn:InteractiveObject;
		//滚动目标
		private var _content:*;
		//遮罩
		private var _mask:DisplayObject;
		//目标滚动的落差高度 = 内容高度 - 遮罩高度
		private var _scrollHeight:Number;
		
		private function delayCall(e:Event):void
		{
			removeEventListener(Event.ENTER_FRAME, delayCall);

			if (_scrollBox) {
				track = _scrollBox['track'];
				thumb = _scrollBox['thumb'];
				up_btn = _scrollBox['up_btn'];
				down_btn = _scrollBox['down_btn'];
				_content = _scrollBox['content'];
				_mask = _scrollBox['mask'];
				_content.mask = _mask;
				_scrollHeight = _content.height - _mask.height;
				
				yMax = thumb.y + (track.height - thumb.height);
				yMin = thumb.y;

				initScroll();
			}
		}
		
		private function onRemoved(e:Event):void
		{
			destroyScroll();
		}
		private function initScroll():void
		{
			addInteractive(thumb, onThumbDown);
			addInteractive(up_btn, onBtnUp);
			addInteractive(down_btn, onBtnDown);
		}
		
		private function onBtnUp(e:MouseEvent):void
		{
			_percent -= _speed;
			if (_percent <= 0) {
				_percent = 0;
			}
			positionContent(_percent);
			positionThumb(_percent);
		}
		
		private function onBtnDown(e:MouseEvent):void
		{
			_percent += _speed;
			if (_percent >= 1) {
				_percent = 1;
				return;
			}
			positionContent(_percent);
			positionThumb(_percent);
		}
		
		private function onThumbDown(e:MouseEvent):void
		{
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onThumbMove);
			stage.addEventListener(MouseEvent.MOUSE_UP,onThumbUp);
			yOffset = (stage.mouseY - thumb.y);
		}
		
		private function onThumbMove(e:MouseEvent):void
		{
			thumb.y = stage.mouseY - yOffset;
			if(thumb.y <= yMin)
			{
				thumb.y = yMin;
				_percent = 0;
			}else if(thumb.y >= yMax)
			{
				thumb.y = yMax;
				_percent = 1;
			}else{
				_percent = ((thumb.y - yMin) / (yMax - yMin));
			}
			positionContent(_percent);
			//trace("CONTENT PERCENT : " + percent * (_scrollContentHeight - _scrollBoxHeight));
			e.updateAfterEvent();
		}
		
		private function onThumbUp(e:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onThumbMove);
		}
		
		public function destroyScroll():void
		{
			trace("ScrollBox: destroyScroll()");
            thumb.removeEventListener(MouseEvent.MOUSE_DOWN, onThumbDown);
            stage.removeEventListener(MouseEvent.MOUSE_UP, onThumbUp);
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onThumbMove);
		}
		
		private function positionThumb(percent:Number):void {
            if (percent >= 1){
                percent = 1;
            }else if (percent <= 0){
                percent = 0;
            }
			TweenLite.to(thumb, 1, { y:(yMin + percent * (yMax - yMin)) } );
        }
		
		private function positionContent(percent:Number):void
		{
			TweenLite.to(_content,1,{y:-((percent * (_scrollHeight))),ease:Quart.easeOut,onUpdate:sendRenderEvent});
		}
		private function sendRenderEvent():void
		{
			dispatchEvent(new ScrollEvent(ScrollEvent.MOVE,_content.y));
		}
		
		private function addInteractive(obj:InteractiveObject,handler:Function):void
		{
			with (obj) {
				if (typeof(obj) != 'SimpleButton') {
					obj.buttonMode = true;
				}
				obj.addEventListener(MouseEvent.MOUSE_DOWN, handler);
			}
		}
		
		/*private var _scrollContentFudge:uint;
		//滚动栏高度，在公用滚动栏情况下，需要调整滚动栏高度时，用此参数，
		//用于改变滚动栏的track的高度/宽度
		private var _scrollBarHeight:uint = 0;*/
		
		//在内容高度发生改变时，更新滚动栏.
		public function update():void
		{
			_scrollHeight = _content.height - _mask.height;
		}
		/**
		 * @param	滚动实例对象设置，包含content、mask、thumb、track、up_btn、down_btn对象。
		 */
		private var _scrollBox:Object;
		public function set scrollBoxUIConfig(value:Object):void { _scrollBox = value; };
		public function get scrollBoxUIConfig():Object { return _scrollBox; }
	}
}